#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "config.h"
#include "audio_handler.h"

// 音频缓冲区
static uint16_t audio_buffer[AUDIO_BUFFER_SIZE];
static uint16_t output_buffer[AUDIO_BUFFER_SIZE];
static volatile int buffer_index = 0;
static volatile int output_index = 0;
static volatile bool recording = false;
static volatile bool playing = false;

// 音频处理状态
static audio_state_t audio_state = AUDIO_IDLE;
static float volume = 0.5f;
static bool mute = false;

// 私有函数声明
static void adc_init(void);
static void pwm_init(void);
static void audio_timer_init(void);
static void audio_interrupt_handler(void);
static float calculate_rms(uint16_t *buffer, int size);
static void apply_audio_filter(uint16_t *buffer, int size);

/**
 * 初始化音频处理模块
 */
int audio_handler_init(void)
{
    DEBUG_PRINT(2, "初始化音频处理模块...");

    // 初始化ADC（麦克风输入）
    adc_init();

    // 初始化PWM（音频输出）
    pwm_init();

    // 初始化音频定时器
    audio_timer_init();

    // 清空缓冲区
    memset(audio_buffer, 0, sizeof(audio_buffer));
    memset(output_buffer, 0, sizeof(output_buffer));

    audio_state = AUDIO_IDLE;
    DEBUG_PRINT(2, "音频处理模块初始化完成");

    return 0;
}

/**
 * 开始录音
 */
int audio_start_recording(void)
{
    if (audio_state == AUDIO_RECORDING)
    {
        DEBUG_PRINT(1, "已经在录音中");
        return -1;
    }

    DEBUG_PRINT(2, "开始录音...");

    // 清空缓冲区
    memset(audio_buffer, 0, sizeof(audio_buffer));
    buffer_index = 0;

    recording = true;
    audio_state = AUDIO_RECORDING;

    // 启动ADC采样
    // TODO: 启动ADC中断采样

    return 0;
}

/**
 * 停止录音
 */
int audio_stop_recording(void)
{
    if (audio_state != AUDIO_RECORDING)
    {
        DEBUG_PRINT(1, "未在录音状态");
        return -1;
    }

    DEBUG_PRINT(2, "停止录音");

    recording = false;
    audio_state = AUDIO_IDLE;

    // 停止ADC采样
    // TODO: 停止ADC中断

    return 0;
}

/**
 * 播放音频数据
 */
int audio_play_data(uint16_t *data, int size)
{
    if (audio_state == AUDIO_PLAYING)
    {
        DEBUG_PRINT(1, "正在播放音频");
        return -1;
    }

    if (size > AUDIO_BUFFER_SIZE)
    {
        DEBUG_PRINT(0, "音频数据过大");
        return -1;
    }

    DEBUG_PRINT(2, "开始播放音频，大小: %d", size);

    // 复制数据到输出缓冲区
    memcpy(output_buffer, data, size * sizeof(uint16_t));
    output_index = 0;

    playing = true;
    audio_state = AUDIO_PLAYING;

    // 启动PWM输出
    // TODO: 启动PWM定时器

    return 0;
}

/**
 * 停止播放
 */
int audio_stop_playing(void)
{
    if (audio_state != AUDIO_PLAYING)
    {
        return 0;
    }

    DEBUG_PRINT(2, "停止播放");

    playing = false;
    audio_state = AUDIO_IDLE;

    // 停止PWM输出
    // TODO: 停止PWM定时器

    return 0;
}

/**
 * 获取录音数据
 */
int audio_get_recording_data(uint16_t *data, int max_size)
{
    if (audio_state == AUDIO_RECORDING)
    {
        DEBUG_PRINT(1, "正在录音中，无法获取数据");
        return -1;
    }

    int copy_size = (buffer_index < max_size) ? buffer_index : max_size;
    memcpy(data, audio_buffer, copy_size * sizeof(uint16_t));

    DEBUG_PRINT(3, "获取录音数据，大小: %d", copy_size);

    return copy_size;
}

/**
 * 检测语音活动
 */
bool audio_detect_voice_activity(void)
{
    if (buffer_index < 100)
    {
        return false;
    }

    // 计算最近100个采样点的RMS值
    float rms = calculate_rms(&audio_buffer[buffer_index - 100], 100);

    // 转换为dB
    float db = 20 * log10(rms / 32768.0f);

    // 语音活动检测阈值
    bool voice_detected = (rms > MIC_THRESHOLD);

    DEBUG_PRINT(3, "语音检测: RMS=%.2f, dB=%.2f, 检测到=%s",
                rms, db, voice_detected ? "是" : "否");

    return voice_detected;
}

/**
 * 设置音量
 */
void audio_set_volume(float vol)
{
    if (vol < 0.0f)
        vol = 0.0f;
    if (vol > 1.0f)
        vol = 1.0f;

    volume = vol;
    DEBUG_PRINT(2, "设置音量: %.2f", volume);
}

/**
 * 获取音量
 */
float audio_get_volume(void)
{
    return volume;
}

/**
 * 设置静音
 */
void audio_set_mute(bool is_mute)
{
    mute = is_mute;
    DEBUG_PRINT(2, "设置静音: %s", mute ? "开" : "关");
}

/**
 * 获取音频状态
 */
audio_state_t audio_get_state(void)
{
    return audio_state;
}

/**
 * 音频处理循环（在主循环中调用）
 */
void audio_process(void)
{
    // 处理录音数据
    if (recording && buffer_index > 0)
    {
        // 应用音频滤波
        apply_audio_filter(audio_buffer, buffer_index);
    }

    // 处理播放数据
    if (playing)
    {
        // 应用音量控制
        if (!mute && output_index < AUDIO_BUFFER_SIZE)
        {
            output_buffer[output_index] = (uint16_t)(output_buffer[output_index] * volume);
        }
    }
}

// 私有函数实现

/**
 * 初始化ADC
 */
static void adc_init(void)
{
    // TODO: 根据EBP3901的具体ADC配置
    // 配置ADC0为连续采样模式
    // 设置采样率为16kHz
    // 启用ADC中断

    DEBUG_PRINT(2, "ADC初始化完成");
}

/**
 * 初始化PWM
 */
static void pwm_init(void)
{
    // TODO: 根据EBP3901的具体PWM配置
    // 配置GPIO4为PWM输出
    // 设置PWM频率和占空比

    DEBUG_PRINT(2, "PWM初始化完成");
}

/**
 * 初始化音频定时器
 */
static void audio_timer_init(void)
{
    // TODO: 配置定时器用于音频采样和播放
    // 设置定时器中断频率为采样率

    DEBUG_PRINT(2, "音频定时器初始化完成");
}

/**
 * 音频中断处理函数
 */
static void audio_interrupt_handler(void)
{
    // 录音处理
    if (recording && buffer_index < AUDIO_BUFFER_SIZE)
    {
        // 从ADC读取数据
        uint16_t sample = 0; // TODO: 从ADC读取
        audio_buffer[buffer_index++] = sample;
    }

    // 播放处理
    if (playing && output_index < AUDIO_BUFFER_SIZE)
    {
        // 输出到PWM
        uint16_t sample = output_buffer[output_index++];
        if (!mute)
        {
            sample = (uint16_t)(sample * volume);
        }
        else
        {
            sample = 0;
        }
        // TODO: 输出到PWM

        // 播放完成
        if (output_index >= AUDIO_BUFFER_SIZE)
        {
            playing = false;
            audio_state = AUDIO_IDLE;
        }
    }
}

/**
 * 计算RMS值
 */
static float calculate_rms(uint16_t *buffer, int size)
{
    if (size <= 0)
        return 0.0f;

    float sum = 0.0f;
    for (int i = 0; i < size; i++)
    {
        float sample = (float)buffer[i] - 32768.0f; // 转换为有符号
        sum += sample * sample;
    }

    return sqrt(sum / size);
}

/**
 * 应用音频滤波
 */
static void apply_audio_filter(uint16_t *buffer, int size)
{
    // 简单的低通滤波器
    static float prev_sample = 0.0f;
    float alpha = 0.1f; // 滤波系数

    for (int i = 0; i < size; i++)
    {
        float current = (float)buffer[i];
        float filtered = alpha * current + (1.0f - alpha) * prev_sample;
        buffer[i] = (uint16_t)filtered;
        prev_sample = filtered;
    }
}